
/*
    Software License

    Copyright (C) 2021-05-24  Xoronos

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, version 3.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

/*
    Liabilities

    The software is provided "AS IS" without any warranty of any kind, either expressed,
    implied, or statutory, including, but not limited to, any warranty that the software
    will conform to specifications, any implied warranties of merchantability, fitness
    for a particular purpose, and freedom from infringement, and any warranty that the
    documentation will conform to the software, or any warranty that the software will
    be error free.

    In no event shall Xoronos be liable for any damages, including, but not limited to,
    direct, indirect, special or consequential damages, arising out of, resulting from,
    or in any way connected with this software, whether or not based upon warranty,
    contract, tort, or otherwise, whether or not injury was sustained by persons or
    property or otherwise, and whether or not loss was sustained from, or arose out of
    the results of, or use of, the software or services provided hereunder.

    To request the provided software under a different license you can contact us at
    support@xoronos.com
*/

#include "test_io_crypto.h"

#if !defined( XRN_MAX_STATE_SIZE )
#define XRN_MAX_STATE_SIZE (XNBITS-1)
#endif
#define IMPOSE_MAX_STATE_SIZE 0

int test_bytes_2_cipher(
 )
{
    int error, padding_start, i, j, crc_bytes, index, length;
    int nequal_data, crc_i;
    uint8_t c, byte, *bytes;
    int nequal_crc, nequal_crc16, nequal_crc8, nequal_crc32, nequal_crc64;
    uint64_t crc64, prev_crc64;
    uint32_t crc32, prev_crc32;
    uint16_t crc16, prev_crc16;
    uint8_t crc8, prev_crc8;
    xstate_t *bv;
    load_variables_t *load_variables;
    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) rand(  ) % 9;
    while ( ( ( settings.crc_bytes >= 5 ) && ( settings.crc_bytes < 8 ) ) || ( settings.crc_bytes == 3 )
            || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) rand(  ) % 9;
    }

    strcpy( settings.rnd_str, "" );
    settings.state_size = ( uint8_t ) rand(  ) % ( XRN_MAX_STATE_SIZE + 1 );
    while ( settings.state_size < 2 ) {
        settings.state_size = ( uint8_t ) rand(  ) % ( XRN_MAX_STATE_SIZE + 1 );
    }

    if ( IMPOSE_MAX_STATE_SIZE ) {
        settings.state_size = XRN_MAX_STATE_SIZE;
    }

    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    for ( i = 0; i < sizeof( settings.encoding_settings ); i++ ) {
        ( ( uint8_t * ) & settings.encoding_settings )[i] = 0;
    }

    // initialize block variables
    load_variables = ( load_variables_t * ) malloc( sizeof( load_variables_t ) );
    bv = ( xstate_t * ) malloc( sizeof( xstate_t ) );
    bv->xnums =
        ( xnum_t * ) malloc( ( uint64_t ) sizeof( xnum_t ) * ( uint64_t ) ( settings.state_size + 1 ) );
    crc_bytes = settings.crc_bytes;

    crypto_init( load_variables, ( uint8_t ) crc_bytes );
    length =
        ( ( ( int ) ( sizeof( xnum_t ) * 8 ) * ( int ) ( settings.state_size + 1 ) ) / 8 -
          2 ) * ( rand(  ) % 5 ) +
        ( rand(  ) % ( ( ( ( int ) sizeof( xnum_t ) * 8 ) * ( int ) ( settings.state_size + 1 ) ) / 8 ) ) + 1;
    bytes = ( uint8_t * ) malloc( ( uint64_t ) sizeof( uint8_t ) * ( uint64_t ) length );

    for ( i = 0; i < length; i++ ) {
        bytes[i] = ( uint8_t ) rand(  );
    }

    i = 0;

    // assuming the test is right
    error = 0;
    index = 0;

    // initializing crc
    prev_crc64 = 0xffffffffffffffff;
    prev_crc32 = 0xffffffff;
    prev_crc16 = 0xffff;
    prev_crc8 = 0xff;
    crc_i = 0;
    crc8 = 0;
    crc16 = 0;
    crc32 = 0;
    crc64 = 0;
    nequal_crc = 0;
    nequal_data = 0;
    byte = bytes[0];
    nequal_crc8 = 1;
    nequal_crc16 = 1;
    nequal_crc32 = 1;
    nequal_crc64 = 1;
    // read all the block and calculate the crc
    while ( ( load_variables->last_block == 0 ) && ( !error ) ) {

        // get the block
        bytes_2_cipher( bytes, length, i, bv, load_variables, settings );

        if ( load_variables->last_block == 1 ) {
            padding_start = padding_start_index( bv, settings );
        } else {
            padding_start = ( ( int ) ( settings.state_size + 1 ) * ( int ) ( sizeof( xnum_t ) * 8 ) ) / 8;
        }

        for ( j = 0; ( j < padding_start ) && ( !error ); j++ ) {
            c = ( ( uint8_t * ) ( bv->xnums ) )[j];

            if ( crc_i == 0 ) {
                xrn_crc64( &c, 1, &prev_crc64 );
                xrn_crc32( &c, 1, &prev_crc32 );
                xrn_crc16( &c, 1, &prev_crc16 );
                xrn_crc8( &c, 1, &prev_crc8 );
            }

            if ( index < length ) {
                byte = bytes[index];
                index++;
                nequal_data = nequal_data || ( c != byte );
            } else {
                nequal_data = 1;
            }

            if ( nequal_data ) {
                if ( crc_i < crc_bytes ) {
                    if ( crc_i < 8 ) {
                        nequal_crc64 = ( c != ( ( uint8_t * ) & crc64 )[crc_i] );
                    }

                    if ( crc_i < 4 ) {
                        nequal_crc32 = ( c != ( ( uint8_t * ) & crc32 )[crc_i] );
                    }

                    if ( crc_i < 2 ) {
                        nequal_crc16 = ( c != ( ( uint8_t * ) & crc16 )[crc_i] );
                    }

                    if ( crc_i < 1 ) {
                        nequal_crc8 = ( c != ( ( uint8_t * ) & crc8 )[crc_i] );
                    }

                    crc_i = crc_i + 1;
                }

                nequal_crc = ( nequal_crc8 && nequal_crc16 && nequal_crc32 && nequal_crc64 );

            }

            error = nequal_data && nequal_crc;
            if ( crc_i == 0 ) {
                crc8 = prev_crc8;
                crc16 = prev_crc16;
                crc32 = prev_crc32;
                crc64 = prev_crc64;
            }

        }

        if ( error ) {

            printf( "either data or crc missmatch in test_bytes_2_cipher\n" );

            free( bytes );
            free( load_variables );
            free( bv->xnums );
            free( bv );
            return 1;
        }

        i = i + 1;
    }

    free( bytes );
    free( load_variables );
    free( bv->xnums );
    free( bv );
    return 0;
}

int test_load_cipher(
 )
{
    FILE *fp0;
    FILE *fp1;
    char fname[256];
    int file_size, error, padding_start, i, j, crc_bytes;
    int nequal_data, crc_i;
    uint8_t c, byte;
    int nequal_crc, nequal_crc16, nequal_crc8, nequal_crc32, nequal_crc64;
    uint64_t crc64, prev_crc64;
    uint32_t crc32, prev_crc32;
    uint16_t crc16, prev_crc16;
    uint8_t crc8, prev_crc8;
    xstate_t *bv;
    load_variables_t *load_variables;
    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) rand(  ) % 9;
    while ( ( ( settings.crc_bytes >= 5 ) && ( settings.crc_bytes < 8 ) ) || ( settings.crc_bytes == 3 )
            || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) rand(  ) % 9;
    }

    strcpy( settings.rnd_str, "" );
    settings.state_size = ( uint8_t ) rand(  ) % ( XRN_MAX_STATE_SIZE + 1 );
    while ( settings.state_size < 2 ) {
        settings.state_size = ( uint8_t ) rand(  ) % ( XRN_MAX_STATE_SIZE + 1 );
    }

    if ( IMPOSE_MAX_STATE_SIZE ) {
        settings.state_size = XRN_MAX_STATE_SIZE;
    }

    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    for ( i = 0; i < sizeof( settings.encoding_settings ); i++ ) {
        ( ( uint8_t * ) & settings.encoding_settings )[i] = 0;
    }

    // initialize block variables
    load_variables = ( load_variables_t * ) malloc( sizeof( load_variables_t ) );
    bv = ( xstate_t * ) malloc( sizeof( xstate_t ) );
    bv->xnums =
        ( xnum_t * ) malloc( ( uint64_t ) sizeof( xnum_t ) * ( uint64_t ) ( settings.state_size + 1 ) );
    crc_bytes = settings.crc_bytes;

    crypto_init( load_variables, ( uint8_t ) crc_bytes );
    file_size =
        ( ( ( ( int ) sizeof( xnum_t ) * 8 ) * ( ( int ) settings.state_size + 1 ) ) / 8 -
          2 ) * ( rand(  ) % 5 ) +
        ( rand(  ) % ( ( ( ( int ) sizeof( xnum_t ) * 8 ) * ( ( int ) settings.state_size + 1 ) ) / 8 ) ) + 1;

    // generate a random file
    strcpy( fname, "../cache/to_remove_load_block_data_test.txt" );
    fp0 = fopen( fname, "wb" );
    c = ( uint8_t ) rand(  ) % 256;
    for ( i = 0; i < file_size; i++ ) {
        c = ( uint8_t ) rand(  ) % 256;
        fputc( c, fp0 );
    }

    fclose( fp0 );

    // read and create
    fp0 = fopen( fname, "rb" );
    fp1 = fopen( fname, "rb" );

    i = 0;

    // assuming the test is right
    error = 0;

    // initializing crc
    prev_crc64 = 0xffffffffffffffff;
    prev_crc32 = 0xffffffff;
    prev_crc16 = 0xffff;
    prev_crc8 = 0xff;
    crc_i = 0;
    crc8 = 0;
    crc16 = 0;
    crc32 = 0;
    crc64 = 0;
    nequal_crc = 0;
    nequal_data = 0;
    nequal_crc8 = 1;
    nequal_crc16 = 1;
    nequal_crc32 = 1;
    nequal_crc64 = 1;

    // read all the block and calculate the crc
    while ( ( load_variables->last_block == 0 ) && ( !error ) ) {

        // get the block
        plain_text_2_cipher( fp0, i, bv, load_variables, settings );

        if ( load_variables->last_block == 1 ) {
            padding_start = padding_start_index( bv, settings );
        } else {
            padding_start = ( ( int ) ( settings.state_size + 1 ) * ( int ) ( sizeof( xnum_t ) * 8 ) ) / 8;
        }

        for ( j = 0; ( j < padding_start ) && ( !error ); j++ ) {
            c = ( ( uint8_t * ) ( bv->xnums ) )[j];

            if ( crc_i == 0 ) {
                xrn_crc64( &c, 1, &prev_crc64 );
                xrn_crc32( &c, 1, &prev_crc32 );
                xrn_crc16( &c, 1, &prev_crc16 );
                xrn_crc8( &c, 1, &prev_crc8 );
            }

            if ( ( load_variables->last_block == 1 ) && ( j >= padding_start - crc_bytes ) ) {
                nequal_data = 1;
            } else {
                byte = ( uint8_t ) fgetc( fp1 );
                nequal_data = nequal_data || ( c != byte );
            }

            if ( nequal_data ) {
                if ( crc_i < crc_bytes ) {
                    if ( crc_i < 8 ) {
                        nequal_crc64 = ( c != ( ( uint8_t * ) & crc64 )[crc_i] );
                    }

                    if ( crc_i < 4 ) {
                        nequal_crc32 = ( c != ( ( uint8_t * ) & crc32 )[crc_i] );
                    }

                    if ( crc_i < 2 ) {
                        nequal_crc16 = ( c != ( ( uint8_t * ) & crc16 )[crc_i] );
                    }

                    if ( crc_i < 1 ) {
                        nequal_crc8 = ( c != ( ( uint8_t * ) & crc8 )[crc_i] );
                    }

                    crc_i = crc_i + 1;

                }

                nequal_crc = ( nequal_crc8 && nequal_crc16 && nequal_crc32 && nequal_crc64 );

            }

            error = nequal_data && nequal_crc;
            if ( crc_i == 0 ) {
                crc8 = prev_crc8;
                crc16 = prev_crc16;
                crc32 = prev_crc32;
                crc64 = prev_crc64;
            }

        }

        if ( error ) {

            printf( "either data or crc missmatch in test_load_cipher\n" );

            fclose( fp0 );
            fclose( fp1 );
            free( load_variables );
            free( bv->xnums );
            free( bv );
            return 1;
        }

        i = i + 1;
    }

    fclose( fp0 );
    fclose( fp1 );
    free( load_variables );
    free( bv->xnums );
    free( bv );
    return 0;
}

int test_from_bytes_2_hash_block(
 )
{
    uint8_t *bytes;
    int length, error;
    int i, j, padding_start, index;

    xstate_t bv;
    hash_load_variables_t hlv;
    uint8_t last_block, c;
    char buff[256];

    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) rand(  ) % 5;
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) rand(  ) % 5;
    }

    strcpy( settings.rnd_str, "" );
    settings.state_size = ( uint8_t ) rand(  ) % ( XRN_MAX_STATE_SIZE + 1 );
    while ( settings.state_size < 2 ) {
        settings.state_size = ( uint8_t ) rand(  ) % ( XRN_MAX_STATE_SIZE + 1 );
    }

    if ( IMPOSE_MAX_STATE_SIZE ) {
        settings.state_size = ( uint8_t ) XRN_MAX_STATE_SIZE;
    }

    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    for ( i = 0; i < sizeof( settings.encoding_settings ); i++ ) {
        ( ( uint8_t * ) & settings.encoding_settings )[i] = 0;
    }

    bv.xnums =
        ( xnum_t * ) malloc( ( uint64_t ) sizeof( xnum_t ) * ( uint64_t ) ( settings.state_size + 1 ) );
    length =
        ( ( ( ( int ) sizeof( xnum_t ) * 8 ) * ( ( int ) settings.state_size + 1 ) ) / 8 -
          2 ) * ( rand(  ) % 5 ) +
        ( rand(  ) % ( ( ( ( int ) sizeof( xnum_t ) * 8 ) * ( ( int ) settings.state_size + 1 ) ) / 8 ) ) + 1;

    bytes = ( uint8_t * ) malloc( ( uint64_t ) sizeof( uint8_t ) * ( uint64_t ) length );
    for ( i = 0; i < length; i++ ) {
        bytes[i] = ( uint8_t ) rand(  );
    }

    crypto_hash_init( &hlv );
    i = 0;
    index = 0;
    last_block = 0;
    error = 0;

    // read all the block and calculate the crc
    while ( ( last_block == 0 ) && ( error == 0 ) ) {

        // get the block
        from_bytes_2_hash_block( bytes, length, i, &bv, &hlv, settings );
        last_block = hlv.last_block;
        if ( last_block == 1 ) {
            padding_start = padding_start_index( &bv, settings );
        } else {
            padding_start = ( ( ( int ) settings.state_size + 1 ) * ( ( int ) sizeof( xnum_t ) * 8 ) ) / 8;
        }

        for ( j = 0; j < padding_start; j++ ) {
            c = ( ( uint8_t * ) ( bv.xnums ) )[j];
            error = c != bytes[index];
            if ( error ) {
                sprintf( buff, "ERR index %5d original %3d read again %3d", index, bytes[index], c );
                free( bv.xnums );
                free( bytes );
                printf( "%s", buff );
                return 1;
            } else {

                //sprintf(buff,"OK  index %5d original %3d read again %3d\n",index,bytes[index],c);PRINT_DEB(buff);
            }

            index++;
        }

        i = i + 1;
    }

    free( bv.xnums );
    free( bytes );

    return error;
}

int test_plain_text_2_hash_block(
 )
{
    FILE *fp, *fp1;
    char fname[256];
    int file_size, error;
    int i, j, padding_start;

    xstate_t bv;
    hash_load_variables_t hlv;
    uint8_t last_block, c, byte;
    char buff[256];

    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) rand(  ) % 5;
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) rand(  ) % 5;
    }

    strcpy( settings.rnd_str, "" );
    settings.state_size = ( uint8_t ) rand(  ) % ( XRN_MAX_STATE_SIZE + 1 );
    while ( settings.state_size < 2 ) {
        settings.state_size = ( uint8_t ) rand(  ) % ( XRN_MAX_STATE_SIZE + 1 );
    }

    if ( IMPOSE_MAX_STATE_SIZE ) {
        settings.state_size = ( uint8_t ) XRN_MAX_STATE_SIZE;
    }

    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    for ( i = 0; i < sizeof( settings.encoding_settings ); i++ ) {
        ( ( uint8_t * ) & settings.encoding_settings )[i] = 0;
    }

    bv.xnums =
        ( xnum_t * ) malloc( ( uint64_t ) sizeof( xnum_t ) * ( uint64_t ) ( settings.state_size + 1 ) );
    file_size =
        ( ( ( ( int ) sizeof( xnum_t ) * 8 ) * ( ( int ) settings.state_size + 1 ) ) / 8 -
          2 ) * ( rand(  ) % 5 ) +
        ( rand(  ) % ( ( ( ( int ) sizeof( xnum_t ) * 8 ) * ( ( int ) settings.state_size + 1 ) ) / 8 ) ) + 1;

    // generate a random file
    strcpy( fname, "../cache/to_remove_xrn_load_hash_block_cipher_test.txt" );
    fp = fopen( fname, "wb" );
    for ( i = 0; i < file_size; i++ ) {
        c = ( uint8_t ) rand(  ) % 256;
        fputc( c, fp );
    }

    fclose( fp );
    crypto_hash_init( &hlv );

    // read and create
    fp = fopen( fname, "rb" );
    fp1 = fopen( fname, "rb" );
    i = 0;
    last_block = 0;
    error = 0;

    // read all the block and calculate the crc
    while ( ( last_block == 0 ) && ( error == 0 ) ) {

        // get the block
        plain_text_2_hash_block( fp, i, &bv, &hlv, settings );
        last_block = hlv.last_block;
        if ( last_block == 1 ) {
            padding_start = padding_start_index( &bv, settings );
        } else {
            padding_start = ( ( ( int ) settings.state_size + 1 ) * ( ( int ) sizeof( xnum_t ) * 8 ) ) / 8;
        }

        for ( j = 0; ( ( j < padding_start ) && ( !error ) ); j++ ) {
            c = ( ( uint8_t * ) ( bv.xnums ) )[j];
            byte = ( uint8_t ) fgetc( fp1 );
            error = ( c != byte );
            if ( error ) {
                free( bv.xnums );
                sprintf( buff, "data error block# %d position %d block %02x file %02x \n", i, j, c & 0xff,
                         byte & 0xff );
                printf( "%s", buff );
                return error;
            }

        }

        i = i + 1;
    }

    free( bv.xnums );
    fclose( fp );
    fclose( fp1 );
    remove( fname );
    return error;
}

int test_io_crypto_all( FILE * fp, int runs, int non_block
 )
{
    time_t t;
    int error;
    int occ;
    char buff[256];
    int v_test_load_cipher;
    int v_test_from_bytes_2_hash_block;
    int v_test_plain_text_2_hash_block;
    int v_test_bytes_2_cipher;

    error = 0;

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_load_cipher = test_load_cipher(  );
        error += v_test_load_cipher;
        printf( "[%4d]", occ );
        if ( !v_test_load_cipher ) {
            printf( "test_io_crypto -> test_load_cipher passed\n" );
            fprintf( fp, "test_io_crypto -> test_load_cipher passed\n" );
        } else {
            printf( "test_io_crypto -> test_load_cipher failed\n" );
            fprintf( fp, "test_io_crypto -> test_load_cipher failed\n" );
        }

        if ( v_test_load_cipher != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_IO_CRYPTO FAILED SEED %ld ", t );
            fprintf( fp, "TEST_IO_CRYPTO FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_IO_CRYPTO FAILED SEED %lld ", t );
            fprintf( fp, "TEST_IO_CRYPTO FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_from_bytes_2_hash_block = test_from_bytes_2_hash_block(  );
        error += v_test_from_bytes_2_hash_block;
        printf( "[%4d]", occ );
        if ( !v_test_from_bytes_2_hash_block ) {
            printf( "test_io_crypto -> test_from_bytes_2_hash_block passed\n" );
            fprintf( fp, "test_io_crypto -> test_from_bytes_2_hash_block passed\n" );
        } else {
            printf( "test_io_crypto -> test_from_bytes_2_hash_block failed\n" );
            fprintf( fp, "test_io_crypto -> test_from_bytes_2_hash_block failed\n" );
        }

        if ( v_test_from_bytes_2_hash_block != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_IO_CRYPTO FAILED SEED %ld ", t );
            fprintf( fp, "TEST_IO_CRYPTO FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_IO_CRYPTO FAILED SEED %lld ", t );
            fprintf( fp, "TEST_IO_CRYPTO FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_bytes_2_cipher = test_bytes_2_cipher(  );
        error += v_test_bytes_2_cipher;
        printf( "[%4d]", occ );
        if ( !v_test_bytes_2_cipher ) {
            printf( "test_io_crypto -> test_bytes_2_cipher passed\n" );
            fprintf( fp, "test_io_crypto -> test_bytes_2_cipher passed\n" );
        } else {
            printf( "test_io_crypto -> test_bytes_2_cipher failed\n" );
            fprintf( fp, "test_io_crypto -> test_bytes_2_cipher failed\n" );
        }

        if ( v_test_bytes_2_cipher != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_IO_CRYPTO FAILED SEED %ld ", t );
            fprintf( fp, "TEST_IO_CRYPTO FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_IO_CRYPTO FAILED SEED %lld ", t );
            fprintf( fp, "TEST_IO_CRYPTO FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_plain_text_2_hash_block = test_plain_text_2_hash_block(  );
        error += v_test_plain_text_2_hash_block;
        printf( "[%4d]", occ );
        if ( !v_test_plain_text_2_hash_block ) {
            printf( "test_io_crypto -> test_plain_text_2_hash_block passed\n" );
            fprintf( fp, "test_io_crypto -> test_plain_text_2_hash_block passed\n" );
        } else {
            printf( "test_io_crypto -> test_plain_text_2_hash_block failed\n" );
            fprintf( fp, "test_io_crypto -> test_plain_text_2_hash_block failed\n" );
        }

        if ( v_test_plain_text_2_hash_block != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_IO_CRYPTO FAILED SEED %ld ", t );
            fprintf( fp, "TEST_IO_CRYPTO FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_IO_CRYPTO FAILED SEED %lld ", t );
            fprintf( fp, "TEST_IO_CRYPTO FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    return error;
}

